<?php
/**
 * author 韩天尊
 * Date: 2022/3/9
 * Email: <724700483@qq.com>
 */

namespace App\HttpController;

use App\Toolys\CustomHttpException;
use App\Toolys\InterfaceData;
use EasySwoole\EasySwoole\Core;
use EasySwoole\EasySwoole\ServerManager;
use EasySwoole\EasySwoole\Trigger;
use EasySwoole\HttpAnnotation\Annotation\ParserInterface;
use EasySwoole\HttpAnnotation\AnnotationController;
use EasySwoole\HttpAnnotation\Exception\Annotation\ParamValidateError;

abstract class BaseController extends AnnotationController
{

    public InterfaceData $writeBack;

    public function __construct(?ParserInterface $parser = null)
    {
        $this->writeBack = new InterfaceData();
        parent::__construct($parser);
    }

    /**
     * 控制器结束时调用 自动回复请求端
     */
    public function little_tail()
    {
        if ($this->writeBack->write_back_type===true && !$this->response()->isEndResponse()){
            $data = $this->writeBack->data;
            $message = $this->writeBack->message;
            if ($this->writeBack->execute == true){
                $this->successful($data, $message);
            }else{
                $this->failure($message, $data);
            }
        }
    }

    /**
     * 获取用户的真实IP
     * @param string $headerName 代理服务器传递的标头名称
     * @return string
     */
    protected function clientRealIP($headerName = 'x-real-ip')
    {
        $server = ServerManager::getInstance()->getSwooleServer();
        $client = $server->getClientInfo($this->request()->getSwooleRequest()->fd);
        $clientAddress = $client['remote_ip'];
        $xri = $this->request()->getHeader($headerName);
        $xff = $this->request()->getHeader('x-forwarded-for');
        if ($clientAddress === '127.0.0.1') {
            if (!empty($xri)) {  // 如果有xri 则判定为前端有NGINX等代理
                $clientAddress = $xri[0];
            } elseif (!empty($xff)) {  // 如果不存在xri 则继续判断xff
                $list = explode(',', $xff[0]);
                if (isset($list[0])) $clientAddress = explode(":", $list[0])[0];
            }
        }
        return $clientAddress;
    }

    protected function input($name, $default = null) {
        $value = $this->request()->getRequestParam($name);
        return $value ?? $default;
    }

    /** 成功的返回
     * @param null $data
     * @param string $msg
     * @param int $code
     * @return bool
     */
    public function successful($data=null, string $msg='success', int $code=1): bool
    {
        $msg = !empty($msg)? $msg : "success";
        return $this->writeJson($code, $data, $msg);
    }

    /** 失敗的返回
     * @param string $msg
     * @param null $data
     * @param int $code
     * @return bool
     */
    public function failure(string $msg='failure', $data=null, int $code=0): bool
    {
        $msg = !empty($msg)? $msg : "failure";
        return $this->writeJson($code, $data, $msg);
    }

    public function afterAction(?string $actionName): void
    {
        parent::afterAction($actionName); // TODO: Change the autogenerated stub
        $this->little_tail();
    }

    /**
     * @param \Throwable $throwable
     * *    author 韩天尊
     */
    protected function onException(\Throwable $throwable): void
    {
        if ($throwable instanceof ParamValidateError) {
            //$msg = $throwable->getValidate()->getError()->getFieldAlias().$throwable->getValidate()->getError()->getErrorRuleMsg();
            $msg = $throwable->getValidate()->getError()->getErrorRuleMsg();
            $this->writeJson(400, null, "{$msg}");
        }elseif ($throwable instanceof CustomHttpException){
            $this->writeJson($throwable->getCode(), $throwable->getData(), $throwable->getMessage());
        } else {
            if (Core::getInstance()->runMode() == 'dev') {
                $this->writeJson(500, null, $throwable->getMessage());
            } else {
                Trigger::getInstance()->throwable($throwable);
                $this->writeJson(500, null, '系统内部错误，请稍后重试');
            }
        }
        $this->writeBack->write_back_type = false;//出错关掉自动回复
    }
}